﻿using System;
using System.Xml;

namespace uForum.Businesslogic
{
	public class Comment
	{

		public int Id { get; set; }
		public int TopicId { get; set; }
		public string MemberId { get; set; }
		public int Position { get; set; }

		public string Body { get; set; }
		public DateTime Created { get; set; }

		private Events _e = new Events();

		public void Delete()
		{
			DeleteEventArgs e = new DeleteEventArgs();
			FireBeforeDelete(e);
			if (!e.Cancel)
			{
				Data.SqlHelper.ExecuteNonQuery("DELETE FROM forumComments WHERE id = @id",
					Data.SqlHelper.CreateParameter("@id", Id));
				Id = 0;
				var topic = new Topic(TopicId);
				if (topic.Exists) topic.Save();
				FireAfterDelete(e);
			}
		}


		public void Save()
		{
			if (Id == 0)
			{

				if (!string.IsNullOrEmpty(Body))
				{
					CreateEventArgs e = new CreateEventArgs();
					FireBeforeCreate(e);
					if (!e.Cancel)
					{
						Data.SqlHelper.ExecuteNonQuery("INSERT INTO forumComments (topicId, memberId, body, position) VALUES(@topicId, @memberId, @body, @position)",
							Data.SqlHelper.CreateParameter("@topicId", TopicId),
							Data.SqlHelper.CreateParameter("@memberId", MemberId),
							Data.SqlHelper.CreateParameter("@body", Body),
							Data.SqlHelper.CreateParameter("@position", Position)
							);

						Created = DateTime.Now;
						Id = Data.SqlHelper.ExecuteScalar<int>("SELECT MAX(id) FROM forumComments WHERE memberId = @memberId",
							Data.SqlHelper.CreateParameter("@memberId", MemberId));

						Topic t = new Topic(TopicId);
						if (t.Exists)
						{
							t.LatestReplyAuthor = MemberId;
							t.Save();
						}

						Forum f = new Forum(t.ParentId);
						if (f.Exists)
						{
							f.SetLatestComment(Id);
							f.SetLatestTopic(t.Id);
							f.SetLatestAuthor(MemberId);
							f.LatestPostDate = DateTime.Now;
							f.Save();
						}


						FireAfterCreate(e);
					}
				}

			}
			else
			{

				UpdateEventArgs e = new UpdateEventArgs();
				FireBeforeUpdate(e);

				if (!e.Cancel)
				{
					Data.SqlHelper.ExecuteNonQuery("UPDATE forumComments SET topicId = @topicId, memberId = @memberId, body = @body, WHERE id = @id",
						Data.SqlHelper.CreateParameter("@topicId", TopicId),
						Data.SqlHelper.CreateParameter("@memberId", MemberId),
						Data.SqlHelper.CreateParameter("@body", Body),
						Data.SqlHelper.CreateParameter("@id", Id)
						);
					FireAfterUpdate(e);
				}
			}
		}


		public Comment() { }
		public Comment(int id)
		{
			umbraco.DataLayer.IRecordsReader dr = Data.SqlHelper.ExecuteReader("SELECT * FROM forumComments WHERE id = " + id);

			if (dr.Read())
			{
				Id = dr.GetInt("id");
				TopicId = dr.GetInt("topicId");
				MemberId = dr.GetString("memberId");

				Body = dr.GetString("body");

				Created = dr.GetDateTime("created");
				Position = dr.GetInt("position");

			}
			else
				throw new ArgumentException(string.Format("No comment exists with id '{0}'", Id));

			dr.Close();
		}

		public static Comment Create(int topicId, string body, string memberId)
		{
			Comment c = new Comment
			{
				TopicId = topicId,
				Body = body,
				MemberId = memberId,
				Created = DateTime.Now,
				Position = (new Topic(topicId).Replies) + 1
			};
			c.Save();

			return c;
		}

		public XmlNode ToXml(XmlDocument d)
		{
			XmlNode tx = d.CreateElement("comment");

			tx.AppendChild(umbraco.xmlHelper.addCDataNode(d, "body", Body));

			tx.Attributes.Append(umbraco.xmlHelper.addAttribute(d, "id", Id.ToString()));
			tx.Attributes.Append(umbraco.xmlHelper.addAttribute(d, "topicId", TopicId.ToString()));
			tx.Attributes.Append(umbraco.xmlHelper.addAttribute(d, "memberId", MemberId));

			tx.Attributes.Append(umbraco.xmlHelper.addAttribute(d, "created", Created.ToString()));

			return tx;
		}



		/* EVENTS */
		public static event EventHandler<CreateEventArgs> BeforeCreate;
		protected virtual void FireBeforeCreate(CreateEventArgs e)
		{
			_e.FireCancelableEvent(BeforeCreate, this, e);
		}
		public static event EventHandler<CreateEventArgs> AfterCreate;
		protected virtual void FireAfterCreate(CreateEventArgs e)
		{
			if (AfterCreate != null)
				AfterCreate(this, e);
		}

		public static event EventHandler<DeleteEventArgs> BeforeDelete;
		protected virtual void FireBeforeDelete(DeleteEventArgs e)
		{
			_e.FireCancelableEvent(BeforeDelete, this, e);
		}
		public static event EventHandler<DeleteEventArgs> AfterDelete;
		protected virtual void FireAfterDelete(DeleteEventArgs e)
		{
			if (AfterDelete != null)
				AfterDelete(this, e);
		}

		public static event EventHandler<UpdateEventArgs> BeforeUpdate;
		protected virtual void FireBeforeUpdate(UpdateEventArgs e)
		{
			_e.FireCancelableEvent(BeforeUpdate, this, e);
		}
		public static event EventHandler<UpdateEventArgs> AfterUpdate;
		protected virtual void FireAfterUpdate(UpdateEventArgs e)
		{
			if (AfterUpdate != null)
				AfterUpdate(this, e);
		}


	}
}
